/*
 * st_queue.h
 *
 *  Created on: 2009-8-10
 *      Author: leaf
 */

#ifndef ST_QUEUE_H_INCLUDED
#define ST_QUEUE_H_INCLUDED
#include <stdint.h>

#ifndef ST_Q_DT
#define ST_Q_DT uint8_t
#endif

struct st_queue{
	uint8_t	front;
	uint8_t back;
	uint8_t sz;
	ST_Q_DT data[1];
};

#define DEF_ST_Q( name, sz ) \
	uint8_t name##_MEM[ (sz - 1) * sizeof(ST_Q_DT) + sizeof(struct st_queue) ];	\
	struct st_queue *name = (struct st_queue *)&name##_MEM;	\
	static const uint8_t name##_MEM_SZ = sz;

#define ST_Q_SZ(q) ( q##_MEM_SZ )

#define st_q_init( q ) { \
	q->sz = ST_Q_SZ(q); \
	q->front = 0; \
	q->back = ST_Q_SZ(q) - 1;\
}

static inline uint8_t st_q_add( uint8_t p, uint8_t off, uint8_t sz )
{
	p += off;
	while( p >= sz ){
		p -= sz;
	}
	return p;
}

static inline void st_q_push( struct st_queue *q, ST_Q_DT d )
{
	q->back = st_q_add( q->back, 1, q->sz );
	q->data[q->back] = d;
}

static inline void st_q_pop( struct st_queue *q )
{
	q->front = st_q_add( q->front, 1, q->sz );
}

static inline ST_Q_DT st_q_front( struct st_queue *q )
{
	return q->data[q->front];
}

#endif /* ST_QUEUE_H_INCLUDED */

